#include "devinsight.h"


PG_MODULE_MAGIC;


/*
 * 总得有个主页吧。 也可在重启后触发内核加载.so
 */
PG_FUNCTION_INFO_V1(devinsight);
extern "C" Datum devinsight(PG_FUNCTION_ARGS);
Datum devinsight(PG_FUNCTION_ARGS)
{
    const char* usage = "一个内核数据结构可视化插件。";
    PG_RETURN_CSTRING(usage);
}


/*
 * 获取t_thrd与u_sess。
 * 防止有些情况下报错 Cannot find thread-loacl var ...
 */
const knl_thrd_context* dviThrd()
{
    return &t_thrd;
}
const knl_session_context* dviUsess()
{
    return u_sess;
}


const char* dviBuffer(Buffer buffer)
{
    StringInfoData res;
    initStringInfo(&res);
    BufferDesc* desc = BufferGetBufferDescriptor(buffer);
    
    appendStringInfo(&res, "Buffer id: %d\n", buffer);
    
    appendStringInfo(&res, "Buffer Desc:\n");
    appendStringInfo(&res, "\trelfilenode:%u/%u/%u %d/%u\n", 
        desc->tag.rnode.spcNode, desc->tag.rnode.dbNode, desc->tag.rnode.relNode, 
        desc->tag.rnode.bucketNode, desc->tag.rnode.opt);
    appendStringInfo(&res, "\tforknum: %d\n", desc->tag.forkNum);
    appendStringInfo(&res, "\tblocknum: %u\n", desc->tag.blockNum);
    
    appendStringInfo(&res, "State: %lu [%s]\n", desc->state, bx64b((void*)&desc->state));
    appendStringInfo(&res, "\t64b-BM_PERMANENT: %s\n", desc->state & BM_PERMANENT ? "true" : "false");
    appendStringInfo(&res, "\t63b-BM_CHECKPOINT_NEEDED: %s\n", desc->state & BM_CHECKPOINT_NEEDED ? "true" : "false");
    appendStringInfo(&res, "\t62b-BM_PIN_COUNT_WAITER: %s\n", desc->state & BM_PIN_COUNT_WAITER ? "true" : "false");
    appendStringInfo(&res, "\t61b-BM_JUST_DIRTIED: %s\n", desc->state & BM_JUST_DIRTIED ? "true" : "false");
    appendStringInfo(&res, "\t60b-BM_IO_ERROR: %s\n", desc->state & BM_IO_ERROR ? "true" : "false");
    appendStringInfo(&res, "\t59b-BM_IO_IN_PROGRESS: %s\n", desc->state & BM_IO_IN_PROGRESS ? "true" : "false");
    appendStringInfo(&res, "\t58b-BM_TAG_VALID: %s\n", desc->state & BM_TAG_VALID ? "true" : "false");
    appendStringInfo(&res, "\t57b-BM_VALID: %s\n", desc->state & BM_VALID ? "true" : "false");
    appendStringInfo(&res, "\t56b-BM_DIRTY: %s\n", desc->state & BM_DIRTY ? "true" : "false");
    appendStringInfo(&res, "\t55b-BM_LOCKED: %s\n", desc->state & BM_LOCKED ? "true" : "false");
    appendStringInfo(&res, "\t54b-BM_IS_TMP_BUF: %s\n", desc->state & BM_IS_TMP_BUF ? "true" : "false");
    appendStringInfo(&res, "\t53-51b-??? \n");
    appendStringInfo(&res, "\t50b-BM_IS_META: %s\n", desc->state & BM_IS_META ? "true" : "false");
    appendStringInfo(&res, "\t49b-BM_IN_MIGRATE: %s\n", desc->state & BM_IN_MIGRATE ? "true" : "false");
    
    appendStringInfo(&res, "\t48-0b - TODO\n");
    
    
    
    appendStringInfo(&res, "Page: (Page)%p\n", BufferGetPage(buffer));
    
    return (const char*)res.data;
}

